import json
import logging
from datetime import datetime, time, timedelta
from os.path import split
from threading import Timer
from urllib.parse import urlparse
import time
import paho.mqtt.client as mqtt
from django.conf import settings
from django.core.management.base import BaseCommand, CommandError
import os
from asset.models import DEV_STATE_ACTIVE, DEV_STATE_UNKOWN, BoardBox
from django.db.models import Q

NOTIFY_BROKER = getattr(settings, "NOTIFY_BROKER", "tcp://211.149.200.96:9883")
DEVICE_ACTIVE_INTERVAL = getattr(settings, "DEVICE_ACTIVE_INTERVAL", 300)
device_update_logger = logging.getLogger("device_update")
connect_logger = logging.getLogger("mqtt_connect")

# on_connect:连接不上的异常判断
# 每个设备的 上一次更新判断
# 长时间未发送消息的设备的状态更改

class Command(BaseCommand):
    '''
    更新设备的状态
    '''
    can_import_settings = True
    help = u'更新设备的状态'
    p = urlparse(NOTIFY_BROKER)
    host, port = p.netloc.split(":")

    def on_connect(self, client, userdata, flags, rc):
        print("Connected with result code "+str(rc))
        # client.subscribe("mr7b/ind/edboard/info/#")
        client.subscribe("edboard/report/#")

    def on_message(self, client, userdata, msg):
        _payload = str(msg.payload, encoding="utf8") or None
        __msg = "[%s]:%s %s" % (datetime.now(), msg.topic, _payload)
        dev_id = msg.topic.split("/")[-2]
        print(__msg)
        try:
            _box = BoardBox.objects.get(id=dev_id)
        except Exception as e:
            device_update_logger.error("Could not find %s device" % dev_id, e)
            print("%s error!" % e)
            return
        if _box.status == DEV_STATE_UNKOWN or _box.status == DEV_STATE_ACTIVE:
            if _payload is None:  # 设备处于非活动状态
                _interval = datetime.now() - _box.state_time
                if _interval.seconds > DEVICE_ACTIVE_INTERVAL:
                    # 设备处于非活动状态
                    print("=====>>> unkown", _interval)
                    _box.status = DEV_STATE_UNKOWN
                    _box.state_time = datetime.now()
            else:
                print("=====>>> active")
                _box.status = DEV_STATE_ACTIVE
                _box.state_time = datetime.now()
            _box.save()

    def timer_check(self):
        print("now: %s" % datetime.now())
        exit_code = os.system('ping -n 2 %s' % self.host)
        timer = Timer(DEVICE_ACTIVE_INTERVAL, self.timer_check)
        timer.setDaemon(True)
        timer.start()
        if exit_code:
            connect_logger.error("connection exception, unable network!")
            return
        # update所有box的状态 | 批量更新
        pre_time = datetime.now() - timedelta(seconds=DEVICE_ACTIVE_INTERVAL)
        board_obj = BoardBox.objects.filter(state_time__lt=pre_time)
        board_obj.filter(status=DEV_STATE_ACTIVE).update(status=DEV_STATE_UNKOWN)
        board_obj.update(state_time=datetime.now())
        print("122222222222222222!")

    def handle(self, *args, **options):
        timer = Timer(2, self.timer_check)
        timer.setDaemon(True)  # 设置线程守护， 是的ctrlC能结束程序
        timer.start()
        client = mqtt.Client()
        client.on_connect = self.on_connect
        client.on_message = self.on_message
        try:
            client.connect(self.host, int(self.port), 60)
            client.loop_forever()
        except Exception as e:
            connect_logger.error("connection exception", e)
            print("connection exception", e)

        # time.sleep(5)
        timer.cancel()
